package com.apes.fn.serveControl.serverParentPackage;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.util.Arith;
import com.apes.framework.util.DateUtil;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Creator: zouyc
 * CreateDate: 2021-03-16 11:29
 * Description:
 **/
public abstract class PControlService extends DomainService implements ControlInterface {

    protected static List checkAndReturnList(Map map){
        Date startDate = returnDate(map.get("DATE_START"));
        Date endDate = returnDate(map.get("DATE_END"));
        check(startDate,endDate);
        List reList= obtainMonthList(startDate,endDate);
        return reList;
    }

    protected static Date returnDate(Object object){
        if(object instanceof  Date){
            return (Date)object;
        }else if (object instanceof String){
            return parseUTC((String) object);
        }else{
            throw new RuntimeException("无法识别的时间格式");
        }
    }

    protected static void check(Object start,Object end){
        boolean tip = false;
        try {
            tip = ((Date)end).before(((Date)start));
        }catch (Exception e){
            throw new RuntimeException("请传入时间格式");
        }
        if(tip) throw new RuntimeException("结束时间不能大于开始时间");
        Optional.ofNullable(start).orElseThrow(()-> new RuntimeException("开始时间不能为空"));
        Optional.ofNullable(start).orElseThrow(()-> new RuntimeException("结束时间不能为空"));
    }

    /**
     * 构建一个开始到结束的年月数组
     * @param sDate
     * @param eDate
     * @return
     */
    protected static List<ArrayList> obtainMonthList(Date sDate, Date eDate){
        List list = new ArrayList();
        Date ssDate = getFirstDayDateOfMonth(sDate);
        Date eeDate = getFirstDayDateOfMonth(eDate);
        int i = 0;
        do{
            i ++;
            JSONObject reJSON = new JSONObject();
            reJSON.put("mouth",DateUtil.format(ssDate,"YYYY-MM"));
            if(ssDate.before(eDate)) list.add(reJSON);
            ssDate = DateUtil.add(ssDate,Calendar.MONTH,1);
        }while (!ssDate.after(eDate) && i< 50);
        return  list;
    }

    /**
     * 获取传入日期的第一天
     * @param date
     * @return
     */
    protected static Date getFirstDayDateOfMonth(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int last = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, last);
        return cal.getTime();
    }

    protected Integer obtainLine(String mouth, JSONArray array, String type) throws Exception {
        JSONObject reJson = (JSONObject) array.stream().filter(item ->{
            JSONObject item1 = (JSONObject)item;
            return mouth.equals(item1.getString("TO_TECHNICAL_AUDIT_DATE"));
        }).findFirst().orElse(new JSONObject());
        return reJson.get(type) == null ? 0 : reJson.getInteger(type);
    }

    /**
     * 添加转化率
     * @param item
     * @param size
     */
    protected void aculate(Object item,Integer size) {
        try {
            if(item instanceof JSONObject){
                JSONObject json = (JSONObject)item;
                json.put("tranRate",size == 0 ? 0 : Arith.round(json.getInteger("AMOUNT")/size,2) > 1 ? 1 : Arith.round(json.getInteger("AMOUNT")/size,2));
            }else{
                throw new RuntimeException("类型不匹配");
            }
        }catch ( Exception e){
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 超时true
     * @param item
     * @return
     */
    protected boolean expiredBoolean(JSONObject item){
        boolean flag = false;
        try {
            flag =  ((JSONObject)item).getBoolean("EXPIRED");
        }catch (Exception e){
            return true;
        }
        return flag;
    }

    protected double getSumDoubl(Object item,String type)  {
        JSONObject json = (JSONObject)item;
        try {
            return Optional.ofNullable(json.getDoubleValue(type)).orElse(0.0);
        }catch (Exception e){
            e.printStackTrace();
            return 0.0;
        }
    }

    protected String groupBy(Object item) {
        JSONObject json = (JSONObject)item;
        return json.getString("CREATE_DATE");
    }


    protected JSONArray createArray() {
        return new JSONArray();
    }


    /**
     * 从frame json 转化为 阿里 json
     * @param json
     * @return
     */
    public static JSONObject tranType(com.apestech.framework.json.JSONObject json){
        return JSONObject.parseObject(JSON.toJSONString(json));
    }

    public static JSONArray tranTypeArray(com.apestech.framework.json.JSONArray array){
        return array.stream().map(item ->tranType((com.apestech.framework.json.JSONObject) item)).collect(Collectors.toCollection(JSONArray::new));
    }

    /**
     * 同比时间点
     * @return
     */
    public JSONObject obtainMonthErlier(JSONObject jo){
        try {
            this.check(jo.getDate("DATE_START"),jo.getDate("DATE_END"));
            jo.put("DATE_START",DateUtil.add(jo.getDate("DATE_START"),Calendar.MONTH,-1));
            jo.put("DATE_END",DateUtil.add(jo.getDate("DATE_END"),Calendar.MONTH,-1));
            return jo;
        }catch (Exception e){
            throw new RuntimeException("获取同比时间出错");
        }
    }

    /**
     * 环比时间
     * @return
     */
    public JSONObject obtainYearErlier(JSONObject jo){
        try {
            this.check(jo.getDate("DATE_START"),jo.getDate("DATE_END"));
            jo.put("DATE_START",DateUtil.add(jo.getDate("DATE_START"),Calendar.YEAR,-1));
            jo.put("DATE_END",DateUtil.add(jo.getDate("DATE_END"),Calendar.YEAR,-1));
            return jo;
        }catch (Exception e){
            throw new RuntimeException("获取同比时间出错");
        }
    }


    protected String obtainMonthErlierDate(String date1){
        String[] strings = date1.split("-");
        if(strings.length != 2) throw new RuntimeException("获取同比时间点出错");
        Integer s1 = Integer.parseInt(strings[1]) - 1 == 0 ? 12 : Integer.parseInt(strings[1]) - 1;

        if(s1 == 12){
            strings[0] = String.valueOf((Integer.parseInt(strings[0]) - 1));
        }
        if(String.valueOf(s1).length() == 1){
            return  strings[0] + "-0" + s1;
        }
        return strings[0] + "-" + s1;
    }

    protected String obtainYearErlierDate(String date1){
        String[] strings = date1.split("-");
        if(strings.length !=2) throw new RuntimeException("获取环比比时间点出错");
        Integer s1 = Integer.parseInt(strings[0]);
        return  (s1 - 1) + "-" +strings[1] ;
    }


    protected double obtainMonthErlierValue(Double currentValue,Double lastValue){
        if(currentValue == null || lastValue == null || currentValue == 0 || lastValue == 0) return 0;
        return Arith.round(currentValue/lastValue,2) * 100;
    }

    protected static java.util.Date parseUTC(String source) {
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(source));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new java.util.Date(calendar.getTimeInMillis());
    }

    /**
     * 获取本月第一天
     * @return
     */
    protected Date obtainMonthStart(){
        Calendar cale = Calendar.getInstance();
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        String strDate = DateUtil.format(cale.getTime(),DateUtil.SHOW_DATE_FORMAT) + " 00:00:00"; //获取第一天时间
        return  DateUtil.parse(strDate,DateUtil.SHOW_DATETIME_FORMAT);
    }

    /**
     * 获取本月最后一天
     * @return
     */
    protected Date obtainMonthEnd(){
        Calendar cale = Calendar.getInstance();
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        String strDate = DateUtil.format(cale.getTime(),DateUtil.SHOW_DATE_FORMAT) + " 23:59:59"; //获取第一天时间
        return  DateUtil.parse(strDate,DateUtil.SHOW_DATETIME_FORMAT);
    }

}